package com.cskaoyan.javase.exception.handle2.throw4;

/**
 * @description: throws关键字
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 在很多时候，我们不满于在方法声明中声明要抛出的异常的类型
 *我们想要直接在方法内部抛出异常
 * 1，使用throw关键字是直接在方法中抛出一个异常对象
 *
 *   概述：
 * ​	  1.在方法体中使用，主动在方法中抛出异常
 * ​	  2.每次只能抛出确定的某一个异常对象
 * 基本语法：
 *   throw 异常对象;
 *
 *
 * 怎么获得一个异常对象呢？
 * 使用异常类的构造方法 创建一个异常对象
 *
 * 注意：
 * 在方法体中显式的使用throw关键字抛出一个异常，当代码运行到这里，是一定会抛出一个异常对象
 * 如果这个异常是运行时异常，它就会自动向上抛出，如果你显式的处理它 它就不会继续向上抛出了 但是这种做法没有意义
 *
 * 如果这个异常是编译时异常，那么程序立刻报错，因为这里有一个编译时异常没有处理。所以需要显式处理该编译时异常：
 * 注意throw一个编译时异常，往往都是和throws关键字一起使用
 * 方法中抛出编译时异常，方法的调用处 会报错，然后强制它处理
 *
 *
 * 在方法中抛出一个异常，相当于使用了return关键字
 * - 方法立刻结束，后面也不能有其它代码了
 * - throw必须位于方法的最后一行
 *
 *
 * 编译期异常和运行期异常的区别?
 * 1，继承层次中的位置不同
 * Exception的子类中只要不是RuntimeException和它的子类，都是编译时异常
 * 2，从代码角度上看：
 *  有一个编译时异常抛出了，产生了，必须显式处理
 *  编译时异常一般是不支持克隆，文件找不到啊，网络资源不通啊，这种需要提前检查并且可以修正的问题
 *  所以这个异常会强制你去检查，如果不处理就报错
 *
 *  如果是运行时异常，代码必须执行起来了，才能够知道有这个异常（jvm）
 *  但是对于程序员而言，运行时异常绝大多数都是编码问题导致的，所以程序一旦出现运行时异常，最好的解决办法
 *  是重构代码，不让程序抛出这个运行时异常
 *  如果情况特殊，也可以try...catch处理运行时异常
 *
 */
public class Demo {
    public static void main(String[] args) {
        try {
            getException();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            System.out.println("处理");

        }
    }

    public static void getException() throws
            CloneNotSupportedException {
        /*
        这样做没有太大意义
        try {
            System.out.println("111111111");
            ArithmeticException ae = new ArithmeticException("/ by zero");
            throw ae;
        } catch (ArithmeticException ae) {
            System.out.println("22222");
        }*/
        //开发中抛出异常 都是直接抛出匿名对象即可
        throw new CloneNotSupportedException("test");
        //System.out.println(); Unreachable statement 相当于是return
    }

    public static int test(int a) {
        if (a > 0) {
            return 0;
        } else {
            throw new RuntimeException("参数异常");
        }
    }
}
